{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "223ec21d",
   "metadata": {},
   "source": [
    "# Instalar um Core open5GS, o RIC O-RAN SC, uma gNB srsRAN e um UE srsRAN, e conectá-los.\n",
    "\n",
    "#### Tutorial baseado em: https://docs.srsran.com/projects/project/en/latest/tutorials/source/near-rt-ric/source/index.html\n",
    "\n",
    "\n",
    "### Instalar dependências\n",
    "```bash\n",
    "sudo apt-get install libzmq3-dev\n",
    "sudo apt-get install libuhd-dev uhd-host\n",
    "```\n",
    "\n",
    "### Instalar o srsRAN:\n",
    "\n",
    "```bash\n",
    "cd ~\n",
    "git clone https://github.com/srsran/srsRAN_Project.git\n",
    "cd srsRAN_Project\n",
    "mkdir build\n",
    "cd build\n",
    "cmake ../ -DENABLE_EXPORT=ON -DENABLE_ZEROMQ=ON\n",
    "make -j`nproc`\n",
    "```\n",
    "\n",
    "Pay extra attention to the cmake console output. Make sure you read the following line:\n",
    "\n",
    "```\n",
    "-- FINDING ZEROMQ.\n",
    "-- Checking for module 'ZeroMQ'\n",
    "--   No package 'ZeroMQ' found\n",
    "-- Found libZEROMQ: /usr/local/include, /usr/local/lib/libzmq.so\n",
    "```\n",
    "\n",
    "### Instalar o srsUE: \n",
    "\n",
    "```bash\n",
    "sudo apt-get install build-essential cmake libfftw3-dev libmbedtls-dev libboost-program-options-dev libconfig++-dev libsctp-dev\n",
    "cd ~\n",
    "git clone https://github.com/srsRAN/srsRAN_4G.git\n",
    "cd srsRAN_4G\n",
    "mkdir build\n",
    "cd build\n",
    "cmake ../\n",
    "make\n",
    "make test\n",
    "sudo make install\n",
    "srsran_install_configs.sh user\n",
    "```\n",
    "\n",
    "### Instalar o O-RAN SC RIC\n",
    "```bash\n",
    "cd ~\n",
    "git clone https://github.com/srsran/oran-sc-ric\n",
    "```\n",
    "\n",
    "\n",
    "### Baixar arquivos de configuração da gNB e do UE\n",
    "\n",
    "```bash\n",
    "wget https://docs.srsran.com/projects/project/en/latest/_downloads/cd7bc1de5ec01c261b2b112e21700e77/gnb_zmq.yaml ~/srsRAN_Project/build/apps/gnb/\n",
    "wget https://docs.srsran.com/projects/project/en/latest/_downloads/fada80ca15bd69b34a0ad8425bbc6560/ue_zmq.conf ~/srsRAN_Project/build/apps/gnb/\n",
    "```\n",
    "\n",
    "## Rodar a rede\n",
    "\n",
    "A seguintes etapas devem ser executadas em terminais separados.\n",
    "\n",
    "1. Open5GS\n",
    "2. NearRT-RIC\n",
    "3. gNB\n",
    "4. UE\n",
    "5. Start IP traffic (e.g., ping)\n",
    "6. xApp\n",
    "\n",
    "\n",
    "### Open5GS Core\n",
    "\n",
    "```bash\n",
    "cd ./srsRAN_Project/docker\n",
    "docker compose up 5gc\n",
    "```\n",
    "\n",
    "### O-RAN SC RIC\n",
    "\n",
    "```bash\n",
    "cd ~/oran-sc-ric\n",
    "docker compose up\n",
    "```\n",
    "\n",
    "O Docker deve baixar e compilar (ao executar pela primeira vez) sete contêineres. Quando todos os contêineres forem implantados com sucesso, a seguinte mensagem deverá ser exibida na saída do console NearRT-RIC:\n",
    "\n",
    "```\n",
    "ric_submgr          | RMR is ready now ...\n",
    "```\n",
    "\n",
    "### gNB\n",
    "```bash\n",
    "cd ~/srsRAN_Project/build/apps/gnb/\n",
    "sudo ./gnb -c gnb_zmq.yaml e2 --addr=\"10.0.2.10\" --bind_addr=\"10.0.2.1\"\n",
    "```\n",
    "\n",
    "A mensagem \"Conectando ao AMF em 10.53.1.2:38412\" indica que o gNB iniciou uma conexão com o núcleo. Já a mensagem \"Conectando ao NearRT-RIC em 127.0.0.1:36421\" indica que o gNB iniciou uma conexão com o NearRT-RIC.\n",
    "\n",
    "Se a tentativa de conexão for bem-sucedida, o seguinte (ou similar) será exibido no console do NearRT-RIC:\n",
    "\n",
    "```\n",
    "ric_rtmgr_sim       | 2024/04/02 11:07:39 POST /ric/v1/handles/associate-ran-to-e2t  body: [{\"E2TAddress\":\"10.0.2.10:38000\",\"ranNamelist\":[\"gnb_001_001_00019b\"]}] elapsed: 10.77µs\n",
    "```\n",
    "\n",
    "### UE\n",
    "\n",
    "```BASH\n",
    "sudo ip netns add ue1\n",
    "cd ~/srsRAN_4G/build/srsue/\n",
    "sudo ./srsue ue_zmq.conf\n",
    "```\n",
    "\n",
    "Se o srsUE se conectar com sucesso à rede, o seguinte (ou similar) deverá ser exibido no console:\n",
    "\n",
    "```\n",
    "Built in Release mode using commit fa56836b1 on branch master.\n",
    "\n",
    "Opening 1 channels in RF device=zmq with args=tx_port=tcp://127.0.0.1:2001,rx_port=tcp://127.0.0.1:2000,base_srate=11.52e6\n",
    "Supported RF device list: UHD zmq file\n",
    "CHx base_srate=11.52e6\n",
    "Current sample rate is 1.92 MHz with a base rate of 11.52 MHz (x6 decimation)\n",
    "CH0 rx_port=tcp://127.0.0.1:2000\n",
    "CH0 tx_port=tcp://127.0.0.1:2001\n",
    "Current sample rate is 11.52 MHz with a base rate of 11.52 MHz (x1 decimation)\n",
    "Current sample rate is 11.52 MHz with a base rate of 11.52 MHz (x1 decimation)\n",
    "Waiting PHY to initialize ... done!\n",
    "Attaching UE...\n",
    "Random Access Transmission: prach_occasion=0, preamble_index=0, ra-rnti=0x39, tti=334\n",
    "Random Access Complete.     c-rnti=0x4601, ta=0\n",
    "RRC Connected\n",
    "PDU Session Establishment successful. IP: 10.45.1.2\n",
    "RRC NR reconfiguration successful.\n",
    "```\n",
    "\n",
    "Fica claro que a conexão foi estabelecida com sucesso quando o UE recebe um IP, o que é visto em \"Estabelecimento de Sessão PDU bem-sucedido\". IP: 10.45.1.2. A conexão NR é então confirmada com a mensagem \"Reconfiguração NR RRC bem-sucedida\".\n",
    "\n",
    "### Iniciar tráfego IP\n",
    "```bash\n",
    "sudo ip netns exec ue1 ping -i 0.1 10.45.1.1\n",
    "```\n",
    "\n",
    "Exemplo de saída de ping:\n",
    "```\n",
    "PING 10.45.1.1 (10.45.1.1) 56(84) bytes of data.\n",
    "64 bytes from 10.45.1.1: icmp_seq=1 ttl=64 time=32.2 ms\n",
    "64 bytes from 10.45.1.1: icmp_seq=2 ttl=64 time=35.3 ms\n",
    "64 bytes from 10.45.1.1: icmp_seq=3 ttl=64 time=38.2 ms\n",
    "64 bytes from 10.45.1.1: icmp_seq=4 ttl=64 time=71.5 ms\n",
    "64 bytes from 10.45.1.1: icmp_seq=5 ttl=64 time=32.9 ms\n",
    "```\n",
    "\n",
    "Além disso, a ferramenta iperf pode ser usada para gerar tráfego com taxas de dados mais altas que o ping. Por exemplo, para enviar tráfego UL do UE, é necessário executar o seguinte comando:\n",
    "\n",
    "```bash\n",
    "sudo ip netns exec ue1 iperf -c 10.45.1.1 -u -b 10M -i 1 -t 60\n",
    "```\n",
    "\n",
    "### Iniciar xApp\n",
    "\n",
    "Para iniciar o exemplo fornecido **kpm_mon_xapp.py**, execute o seguinte comando no diretório oran-sc-ric:\n",
    "\n",
    "```bash\n",
    "cd ~/oran-sc-ric\n",
    "docker compose exec python_xapp_runner ./kpm_mon_xapp.py --metrics=DRB.UEThpDl,DRB.UEThpUl --kpm_report_style=5\n",
    "```\n",
    "\n",
    "O xApp permite a assinatura de todos os Estilos de Relatório do E2SM-KPM (ou seja, 1 a 5) e a definição dos nomes das métricas. Com os parâmetros acima, o xApp deve assinar as medições DRB.UEThpUl e DRB.UEThpUl e exibir o conteúdo das mensagens RIC_INDICATION recebidas. A saída do console do xApp deve ser semelhante a:\n",
    "\n",
    "```\n",
    "RIC Indication Received from gnb_001_001_00019b for Subscription ID: 5, KPM Report Style: 5\n",
    "E2SM_KPM RIC Indication Content:\n",
    "-ColletStartTime:  2024-04-02 13:24:56\n",
    "-Measurements Data:\n",
    "--UE_id: 0\n",
    "---granulPeriod: 1000\n",
    "---Metric: DRB.UEThpDl, Value: [7]\n",
    "---Metric: DRB.UEThpUl, Value: [7]\n",
    "```\n"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
